﻿using log4net;
using log4net.Config;
using log4net.Repository;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using AntJoin.Core.Common;

namespace AntJoin.Log
{
    public class LogHelper
    {
        #region 接入阿里云日志服务
        private static ILoggerRepository repository = LogManager.CreateRepository("NETCoreRepository");
        private static ILog _sysLogger = LogManager.GetLogger(Assembly.GetCallingAssembly(), "System");
        private static ILog _infoLogger = LogManager.GetLogger(Assembly.GetCallingAssembly(), "Info");
        private static ILog _appClient = LogManager.GetLogger(Assembly.GetCallingAssembly(), "AppClient");
        private static ILog _operationalLogger = LogManager.GetLogger(Assembly.GetCallingAssembly(), "Operational");
        private static LogReader _logReader = new LogReader();
        private static Random random = new Random();
        private static STSLogin StsLogin = new STSLogin();

        public LogHelper()
        {
            log4net.Config.XmlConfigurator.Configure(repository, new FileInfo(Path.Combine(System.Threading.Thread.GetDomain().BaseDirectory, "log4net.config")));
        }

        /// <summary>
        /// 写入日志
        /// </summary>
        /// <param name="level">日志级别</param>
        /// <param name="info">日志信息</param>
        public static void Log(LogLevel level, object info)
        {
            switch (level)
            {
                case LogLevel.Fatal:
                    _sysLogger.Fatal(info);
                    break;
                case LogLevel.ERROR:
                    _sysLogger.Error(info);
                    break;
                case LogLevel.WARN:
                    _infoLogger.Warn(info);
                    break;
#if DEBUG
                case LogLevel.DEBUG:
                    _infoLogger.Debug(info);
                    break;
#endif
                case LogLevel.INFO:
                    _infoLogger.Info(info);
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// 写入错误日志
        /// </summary>
        /// <param name="level">日志级别</param>
        /// <param name="info">日志信息</param>
        /// <param name="ex">异常</param>
        public static void Log(LogLevel level, object info, Exception ex)
        {
            //string errMsg = ExceptionUtils.GetErrorMsg(ex);
            //message = message + Environment.NewLine + errMsg;
            switch (level)
            {
                case LogLevel.Fatal:
                    _sysLogger.Fatal(info, ex);
                    break;
                case LogLevel.ERROR:
                    _sysLogger.Error(info, ex);
                    break;
                case LogLevel.WARN:
                    _sysLogger.Warn(info, ex);
                    break;
#if DEBUG
                case LogLevel.DEBUG:
                    _sysLogger.Debug(info, ex);
                    break;
#endif
                case LogLevel.INFO:
                    _sysLogger.Info(info, ex);
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// 写入运营日志
        /// </summary>
        /// <param name="topic"></param>
        /// <param name="data"></param>
        public static void Log<T>(OperationalTopic topic, T data) where T : LogEntityBase
        {
            string temp = DateTime.Now.ToString("yyMMddHHmmssfff") + random.Next(0, 999).ToString("000");
            data.ID = data.GetType().Name + "_" + temp.ToString();
            _operationalLogger.Info(new OperationalData() { Topic = topic.ToString(), Data = data });
        }

        /// <summary>
        /// 获取日志列表信息（分页）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="topic"></param>
        /// <param name="query"></param>
        /// <param name="startTime"></param>
        /// <param name="endTime"></param>
        /// <param name="page"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public static List<T> GetLogs<T>(OperationalTopic topic, string query, DateTime startTime, DateTime endTime, int page, int pageSize) where T : LogEntityBase
        {
            return _logReader.GetLogs<T>(topic, query, startTime, endTime, page, pageSize);
        }
        /// <summary>
        /// 获取日志列表信息（全部）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="topic"></param>
        /// <param name="query"></param>
        /// <param name="startTime"></param>
        /// <param name="endTime"></param>
        /// <returns></returns>
        public static List<T> GetLogs<T>(OperationalTopic topic, string query, DateTime startTime, DateTime endTime) where T : LogEntityBase
        {
            List<T> list = new List<T>();
            int count;
            int i = 1;
            do
            {
                var logs = _logReader.GetLogs<T>(topic, query, startTime, endTime, i, 100);
                if (logs == null)
                {
                    break;
                }
                else
                {
                    count = logs.Count;
                    list.AddRange(logs);
                    i++;
                }
            }
            while (count == 100);
            return list;
        }

        /// <summary>
        /// 获取日志分析结果
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="topic"></param>
        /// <param name="query"></param>
        /// <param name="startTime"></param>
        /// <param name="endTime"></param>
        /// <returns></returns>
        public static List<T> GetLogResult<T>(OperationalTopic topic, string query, DateTime startTime, DateTime endTime) where T : class
        {
            return _logReader.GetLogResult<T>(topic, query, startTime, endTime);
        }

        /// <summary>
        /// App日志写入
        /// </summary>
        /// <param name="message"></param>
        public static void AddAppInfo(string message)
        {
            _appClient.Info(message);
        }

        /// <summary>
        /// 获取日志查询页面URL
        /// </summary>
        /// <param name="query">预置的查询条件</param>
        /// <returns></returns>
        public static string GetLogSearchUrl(string query)
        {
            return GetLogSearchUrl(LogCommon.config.GetValue(LogCommon.ProjectName), LogCommon.config.GetValue(LogCommon.StoreName), query);
        }

        /// <summary>
        /// 获取日志查询页面URL
        /// </summary>
        /// <param name="projectName">项目名</param>
        /// <param name="logStoreName">日志库名</param>
        /// <param name="query">预置的查询条件</param>
        /// <returns></returns>
        public static string GetLogSearchUrl(string projectName, string logStoreName, string query)
        {
            string url = string.Format("https://sls4service.console.aliyun.com/next/project/{0}/logsearch/{1}?isShare=true&hideTopbar=true&hideSidebar=true&readOnly=true&theme=dark&sls_iframe=true&queryString={2}",
                LogCommon.config.GetValue(LogCommon.ProjectName), LogCommon.config.GetValue(LogCommon.StoreName), query);
            string logUrl = StsLogin.GetSignInUrl("http://console.gzkuaixiang.com/", url);
            return logUrl;
        }

        /// <summary>
        /// 获取日志仪表盘页面URL
        /// </summary>
        /// <param name="deshboardName">仪表盘ID</param>
        /// <param name="autoFresh">设置自动刷新，如：30s，5m</param>
        /// <returns></returns>
        public static string GetDeshboardUrl(string deshboardName, string autoFresh = null)
        {
            return GetDeshboardUrl(LogCommon.config.GetValue(LogCommon.ProjectName), deshboardName, autoFresh);
        }

        /// <summary>
        /// 获取日志仪表盘页面URL
        /// </summary>
        /// <param name="projectName"></param>
        /// <param name="deshboardName"></param>
        /// <param name="autoFresh"></param>
        /// <returns></returns>
        public static string GetDeshboardUrl(string projectName, string deshboardName, string autoFresh = null)
        {
            string url = string.Format("https://sls4service.console.aliyun.com/next/project/{0}/dashboard/{1}?isShare=true&hideTopbar=true&hideSidebar=true&readOnly=true&theme=dark&sls_iframe=true",
                projectName, deshboardName);
            if (autoFresh != null)
            {
                url += string.Format("&autoFresh={0}", autoFresh);
            }
            string deshUrl = StsLogin.GetSignInUrl("http://console.gzkuaixiang.com/", url);
            return deshUrl;
        }
        #endregion
    }
}
